<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="keywords" content="Hexo Theme Keep">
    <meta name="description" content="Hexo Theme Keep">
    <meta name="author" content="cheng5.du">
    
    <title>
        
            你知道的Vue Router |
        
        cheng5.du
    </title>
    
<link rel="stylesheet" href="/css/style.css">

    <link rel="shortcut icon" href="/images/avatar.jpeg">
    
<link rel="stylesheet" href="/css/font-awesome.min.css">

    <script id="hexo-configurations">
    let KEEP = window.KEEP || {};
    KEEP.hexo_config = {"hostname":"example.com","root":"/","language":"zh-CN"};
    KEEP.theme_config = {"toc":{"enable":false,"number":false,"expand_all":false,"init_open":false},"style":{"primary_color":"#0066CC","avatar":"/images/avatar.jpeg","favicon":"/images/avatar.jpeg","article_img_align":"left","left_side_width":"260px","content_max_width":"920px","hover":{"shadow":false,"scale":false},"first_screen":{"enable":true,"background_img":"/images/bg.svg","description":"人生海海，来日方长。"},"scroll":{"progress_bar":{"enable":false},"percent":{"enable":false}}},"local_search":{"enable":false,"preload":false},"code_copy":{"enable":false,"style":"default"},"pjax":{"enable":false},"lazyload":{"enable":false},"version":"3.4.5"};
    KEEP.language_ago = {"second":"%s 秒前","minute":"%s 分钟前","hour":"%s 小时前","day":"%s 天前","week":"%s 周前","month":"%s 个月前","year":"%s 年前"};
  </script>
<meta name="generator" content="Hexo 6.1.0"></head>


<body>
<div class="progress-bar-container">
    

    
</div>


<main class="page-container">

    

    <div class="page-main-content">

        <div class="page-main-content-top">
            <header class="header-wrapper">

    <div class="header-content">
        <div class="left">
            
            <a class="logo-title" href="/">
                cheng5.du
            </a>
        </div>

        <div class="right">
            <div class="pc">
                <ul class="menu-list">
                    
                        <li class="menu-item">
                            <a class=""
                               href="/"
                            >
                                首页
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/archives"
                            >
                                归档
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/categories"
                            >
                                分类
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/tags"
                            >
                                标签
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/netease"
                            >
                                网抑云
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/about"
                            >
                                关于我
                            </a>
                        </li>
                    
                    
                </ul>
            </div>
            <div class="mobile">
                
                <div class="icon-item menu-bar">
                    <div class="menu-bar-middle"></div>
                </div>
            </div>
        </div>
    </div>

    <div class="header-drawer">
        <ul class="drawer-menu-list">
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/">首页</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/archives">归档</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/categories">分类</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/tags">标签</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/netease">网抑云</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/about">关于我</a>
                </li>
            
        </ul>
    </div>

    <div class="window-mask"></div>

</header>


        </div>

        <div class="page-main-content-middle">

            <div class="main-content">

                
                    <div class="fade-in-down-animation">
    <div class="article-content-container">

        <div class="article-title">
            <span class="title-hover-animation">你知道的Vue Router</span>
        </div>

        
            <div class="article-header">
                <div class="avatar">
                    <img src="/images/avatar.jpeg">
                </div>
                <div class="info">
                    <div class="author">
                        <span class="name">cheng5.du</span>
                        
                    </div>
                    <div class="meta-info">
                        <div class="article-meta-info">
    <span class="article-date article-meta-item">
        <i class="fas fa-edit"></i>&nbsp;
        <span class="pc">2021-06-12 09:33:19</span>
        <span class="mobile">2021-06-12 09:33</span>
    </span>
    
        <span class="article-categories article-meta-item">
            <i class="fas fa-folder"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/categories/%E5%89%8D%E7%AB%AF/">前端</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    
    
        <span class="article-tags article-meta-item">
            <i class="fas fa-tags"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/tags/JavaScript/">JavaScript</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/%E4%BD%A0%E7%9F%A5%E9%81%93%E7%9A%84%E7%B3%BB%E5%88%97/">你知道的系列</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/Vue-Router/">Vue Router</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    

    
    
    
    
</div>

                    </div>
                </div>
            </div>
        

        <div class="article-content markdown-body">
            <h2 id="Vue-Router"><a href="#Vue-Router" class="headerlink" title="Vue Router"></a>Vue Router</h2><blockquote>
<p>Vue Router 是 Vue.js 官方的路由管理器。</p>
</blockquote>
<h3 id="使用概览"><a href="#使用概览" class="headerlink" title="使用概览"></a>使用概览</h3><h4 id="router-js"><a href="#router-js" class="headerlink" title="router.js"></a>router.js</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">Vue</span> <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">VueRouter</span> <span class="keyword">from</span> <span class="string">&#x27;vue-router&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">DashBoard</span> <span class="keyword">from</span> <span class="string">&#x27;../views/DashBoard.vue&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="title class_">Vue</span>.<span class="title function_">use</span>(<span class="title class_">VueRouter</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> routes = [</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="attr">path</span>: <span class="string">&#x27;/&#x27;</span>,</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&#x27;HomePage&#x27;</span>,</span><br><span class="line">    <span class="attr">component</span>: <span class="function">() =&gt;</span> <span class="title function_">import</span>(<span class="string">&#x27;../views/home.vue&#x27;</span>)</span><br><span class="line">  &#125;,</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="attr">path</span>: <span class="string">&#x27;/dashboard&#x27;</span>,</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&#x27;DashBoard&#x27;</span>,</span><br><span class="line">    <span class="attr">component</span>: <span class="title class_">DashBoard</span>,</span><br><span class="line">    <span class="attr">children</span>: []</span><br><span class="line">  &#125;</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> router = <span class="keyword">new</span> <span class="title class_">VueRouter</span>(&#123;</span><br><span class="line">  <span class="attr">mode</span>: <span class="string">&#x27;hash&#x27;</span> || <span class="string">&#x27;history&#x27;</span>,</span><br><span class="line">  <span class="attr">base</span>: process.<span class="property">env</span>.<span class="property">BASE_URL</span>,</span><br><span class="line">  routes,</span><br><span class="line">  scrollBehavior (to, <span class="keyword">from</span>, savePosition) &#123;</span><br><span class="line">    <span class="keyword">return</span> savePosition || &#123; <span class="attr">x</span>: <span class="number">0</span>, <span class="attr">y</span>: <span class="number">0</span> &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 解决重复点击跳转router时报错问题</span></span><br><span class="line"><span class="comment">// Avoided redundant navigation to current location</span></span><br><span class="line"><span class="keyword">const</span> originalPush = <span class="title class_">VueRouter</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">push</span></span><br><span class="line"><span class="title class_">VueRouter</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">push</span> = <span class="keyword">function</span> <span class="title function_">push</span> (location) &#123;</span><br><span class="line">  <span class="keyword">return</span> originalPush.<span class="title function_">call</span>(<span class="variable language_">this</span>, location).<span class="title function_">catch</span>(<span class="function"><span class="params">err</span> =&gt;</span> err)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> router</span><br></pre></td></tr></table></figure>

<h4 id="挂载-main-js"><a href="#挂载-main-js" class="headerlink" title="挂载 - main.js"></a>挂载 - main.js</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">Vue</span> <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span></span><br><span class="line"><span class="keyword">import</span> router <span class="keyword">from</span> <span class="string">&#x27;./router&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  router</span><br><span class="line">&#125;).$mount(<span class="string">&#x27;#app&#x27;</span>)</span><br></pre></td></tr></table></figure>

<h3 id="mode选择"><a href="#mode选择" class="headerlink" title="mode选择"></a>mode选择</h3><blockquote>
<p>默认的是hash模式，我们可以配置成history模式。</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mode = options.<span class="property">mode</span> || <span class="string">&#x27;hash&#x27;</span></span><br></pre></td></tr></table></figure>

<h4 id="具体实现类"><a href="#具体实现类" class="headerlink" title="具体实现类"></a>具体实现类</h4><p>参数mode字符串只是一个标记，实际起作用的是history的实现类:</p>
<p>🚨 Notice：如果是<strong>非浏览器环境</strong>，会<strong>强制</strong>性转换成‘<strong>abstract</strong>’模式</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">switch</span> (mode) &#123;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">&#x27;hash&#x27;</span>:</span><br><span class="line">    <span class="comment">// fallback：如果浏览器不支持，&#x27;history&#x27;模式回滚回&#x27;hash&#x27;</span></span><br><span class="line">    <span class="comment">// this.fallback = mode === &#x27;history&#x27; &amp;&amp; !supportsPushState</span></span><br><span class="line">    <span class="comment">// if (this.fallback) mode = &#x27;hash&#x27;</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">history</span> = <span class="keyword">new</span> <span class="title class_">HashHistory</span>(<span class="variable language_">this</span>, options.<span class="property">base</span>, <span class="variable language_">this</span>.<span class="property">fallback</span>)</span><br><span class="line">    <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">&#x27;history&#x27;</span>:</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">history</span> = <span class="keyword">new</span> <span class="title class_">HTML5History</span>(<span class="variable language_">this</span>, options.<span class="property">base</span>)</span><br><span class="line">    <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">&#x27;abstract&#x27;</span>:</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">history</span> = <span class="keyword">new</span> <span class="title class_">AbstractHistory</span>(<span class="variable language_">this</span>, options.<span class="property">base</span>)</span><br><span class="line">    <span class="keyword">break</span>;</span><br><span class="line">  <span class="attr">default</span>:</span><br><span class="line">    <span class="keyword">if</span> (process.<span class="property">env</span>.<span class="property">NODE_ENV</span> !== <span class="string">&#x27;production&#x27;</span>) &#123;</span><br><span class="line">      <span class="title function_">assert</span>(<span class="literal">false</span>, <span class="string">`invalid mode: <span class="subst">$&#123;mode&#125;</span>`</span>)</span><br><span class="line">    &#125;      </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="push-x2F-replace-x2F-onReady"><a href="#push-x2F-replace-x2F-onReady" class="headerlink" title="push()&#x2F;replace()&#x2F;onReady()"></a>push()&#x2F;replace()&#x2F;onReady()</h4><p>VueRouter类中暴露出来的这些方法，其实只是一个代理，实际调用的是具体的this.history对象的对应方法。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">push (<span class="attr">location</span>: <span class="title class_">RawLocation</span>, onComplete?: <span class="title class_">Funciton</span>, onAbort?: <span class="title class_">Function</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">history</span>.<span class="title function_">push</span>(location, onComplete, onAbort)</span><br><span class="line">&#125;</span><br><span class="line">replace (<span class="attr">location</span>: <span class="title class_">RawLocation</span>, onComplete?: <span class="title class_">Funciton</span>, onAbort?: <span class="title class_">Function</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">history</span>.<span class="title function_">replace</span>(location, onComplete, onAbort)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="hash"><a href="#hash" class="headerlink" title="hash"></a>hash</h4><p>利用URL中的hash(#)，例如：<a class="link"   target="_blank" rel="noopener" href="http://www.test.com/#/test" >www.test.com/#/test<i class="fas fa-external-link-alt"></i></a></p>
<h5 id="hash特点"><a href="#hash特点" class="headerlink" title="hash特点"></a>hash特点</h5><ol>
<li><p>hash虽然出现在URL中，但<strong>不会包括在HTTP请求中</strong>，它是用来<strong>指导浏览器动作</strong>的，对服务器端无用，因此，<strong>hash改变不会重新加载页面</strong>。</p>
</li>
<li><p>每一次<strong>改变hash</strong>（window.location.hash），都会在浏览器的<strong>访问历史中新增一条记录</strong>。</p>
</li>
<li><p>可以为hash改变添加监听事件</p>
 <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;hashchange&#x27;</span>, funcRef, <span class="literal">false</span>)</span><br><span class="line"></span><br><span class="line">setupListeners () &#123;</span><br><span class="line">  <span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;hashchange&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="title function_">ensureSlash</span>()) <span class="keyword">return</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="title function_">transitionTo</span>(<span class="title function_">getHash</span>(), <span class="function"><span class="params">route</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="title function_">replaceHash</span>(route.<span class="property">fullPath</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ol>
<p>利用以上特点，实现前端路由“更新视图但不重新加载页面”。</p>
<h4 id="history"><a href="#history" class="headerlink" title="history"></a>history</h4><p>利用HTML5 History interface新增的方法。（pushState()&#x2F;replaceState()）</p>
<p>例如：<a class="link"   target="_blank" rel="noopener" href="http://www.test.com/test" >www.test.com/test<i class="fas fa-external-link-alt"></i></a></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// @param stateObj 当浏览器跳转到新的状态时，将触发popState事件，该事件将携带stateObj参数的副本</span></span><br><span class="line"><span class="comment">// @param title 所添加记录的标题</span></span><br><span class="line"><span class="comment">// @param URL 所添加记录的URL</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="property">history</span>.<span class="title function_">pushState</span>(stateObj, title, <span class="variable constant_">URL</span>)</span><br><span class="line"><span class="variable language_">window</span>.<span class="property">history</span>.<span class="title function_">replaceState</span>(stateObj, title, <span class="variable constant_">URL</span>)</span><br></pre></td></tr></table></figure>

<h5 id="history特点"><a href="#history特点" class="headerlink" title="history特点"></a>history特点</h5><ol>
<li>当调用他们修改浏览器历史纪录栈后，虽然当前URL改变了，但浏览器不会立即发送请求该URL(The browser won’t attempt to load this URL after a call to pushState()&#x2F;replaceState())。</li>
<li>这就为history模式前页面应用前端路由“更新视图但不重新请求页面”提供了基础。</li>
</ol>
<h5 id="history模式刷新404处理"><a href="#history模式刷新404处理" class="headerlink" title="history模式刷新404处理"></a>history模式刷新404处理</h5><ol>
<li>后端处理</li>
<li>Nginx配置</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">location / &#123;</span><br><span class="line">  root html;</span><br><span class="line">  index index.<span class="property">html</span> index.<span class="property">htm</span>;</span><br><span class="line">  <span class="comment">// 尝试读取$uri(当前请求路径)</span></span><br><span class="line">  <span class="comment">// 读取不到在读取$uri/这个文件夹下的首页</span></span><br><span class="line">  <span class="comment">// 还是读取不到就返回 根目录下的index.html</span></span><br><span class="line">  try_files $uri $uri/ /index.<span class="property">html</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="history比hash的优势"><a href="#history比hash的优势" class="headerlink" title="history比hash的优势"></a>history比hash的优势</h3><ol>
<li>hash会带着#，<strong>很丑</strong></li>
<li>pushState设置的新的URL可以时<strong>当前URL同源的任意URL</strong>；而hash只能修改#后面的部分，故只能设置于当前<strong>同文档的URL</strong></li>
<li>pushState设置的URL<strong>可以与当前的URL一摸一样</strong>，这样也可以添加到浏览器的历史纪录栈中；而hash设置的值必须与原来的<strong>不一样</strong>才能触发添加</li>
<li>pushState可以通过stateObj添加<strong>任意类型的数据</strong>到记录中；hash只能添加<strong>短字符串</strong></li>
<li>pushState可额外<strong>设置title</strong>属性供后续使用</li>
</ol>
<h3 id="源码"><a href="#源码" class="headerlink" title="源码"></a>源码</h3><p><a class="link"   target="_blank" rel="noopener" href="https://github.com/vuejs/vue-router" >vue-router github地址<i class="fas fa-external-link-alt"></i></a></p>
<p><img src="https://cdn.jsdelivr.net/gh/superFatDu/blogPics@main/20210609/vue-router-tree.1ic04gm1ghfk.png" alt="vue-router-tree"></p>
<h3 id="模拟实现"><a href="#模拟实现" class="headerlink" title="模拟实现"></a>模拟实现</h3><h4 id="实现思路"><a href="#实现思路" class="headerlink" title="实现思路"></a>实现思路</h4><ol>
<li>创建VueRouter插件，静态方法install<ol>
<li>判断插件是否已经被加载</li>
<li>当Vue加载时把传入的router对象挂载到Vue的实例上（只执行一次）</li>
</ol>
</li>
<li>创建VueRouter类<ol>
<li>在构造函数中初始化、options、routeMap、app(简化操作，创建Vue实例作为响应式数据记录当前路径)</li>
<li>initRouteMap()遍历所有路由信息，把组件和路由的映射记录到routeMap对象中</li>
<li>注册popstate事件，当路由地址发生变化，重新记录当前的路径</li>
<li>创建router-link和router-view组件</li>
<li>当路径改变的时候通过当前路径在routeMap对象中找到对应的组件，渲染router-view</li>
</ol>
</li>
</ol>
<h4 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h4><h5 id="创建VueRouter插件"><a href="#创建VueRouter插件" class="headerlink" title="创建VueRouter插件"></a>创建VueRouter插件</h5><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">VueRouter</span> &#123;</span><br><span class="line">  <span class="keyword">static</span> <span class="title function_">install</span>(<span class="params">Vue</span>) &#123;</span><br><span class="line">    <span class="comment">// 判断插件是否已经被加载</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="title class_">VueRouter</span>.<span class="property">install</span>.<span class="property">installed</span> &amp;&amp; _Vue === <span class="title class_">Vue</span>) <span class="keyword">return</span></span><br><span class="line">    <span class="comment">// 没加载时，初始化</span></span><br><span class="line">    <span class="title class_">VueRouter</span>.<span class="property">install</span>.<span class="property">installed</span> = <span class="literal">true</span></span><br><span class="line">    _Vue = <span class="title class_">Vue</span></span><br><span class="line"></span><br><span class="line">    <span class="title class_">Vue</span>.<span class="title function_">mixin</span>(&#123;</span><br><span class="line">      <span class="title function_">beforeCreate</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="comment">// 当Vue加载时把传入的router对象挂载到Vue的实例上</span></span><br><span class="line">        <span class="keyword">if</span> (<span class="variable language_">this</span>.<span class="property">$options</span>.<span class="property">router</span>) &#123;</span><br><span class="line">          _Vue.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">$router</span> = <span class="variable language_">this</span>.<span class="property">$options</span>.<span class="property">router</span></span><br><span class="line"></span><br><span class="line">          <span class="comment">// 初始化插件，调用init</span></span><br><span class="line">          <span class="variable language_">this</span>.<span class="property">$options</span>.<span class="property">router</span>.<span class="title function_">init</span>()</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">constrctor</span>(<span class="params">options</span>) &#123;</span><br><span class="line">    <span class="comment">// 存储参数</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">options</span> = options</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">routeMap</span> = &#123;&#125;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">app</span> = <span class="keyword">new</span> <span class="title function_">_Vue</span>(&#123;</span><br><span class="line">      <span class="attr">data</span>: &#123;</span><br><span class="line">        <span class="attr">current</span>: <span class="string">&#x27;/&#x27;</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 组件和路由的映射</span></span><br><span class="line">  <span class="title function_">initRouteMap</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">options</span>.<span class="property">routes</span>.<span class="title function_">forEach</span>(<span class="function"><span class="params">route</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">routeMap</span>[route.<span class="property">path</span>] = route.<span class="property">component</span></span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 实现router-link和router-view组件</span></span><br><span class="line">  <span class="title function_">initComponents</span>(<span class="params"></span>) &#123;</span><br><span class="line">    _Vue.<span class="title function_">component</span>(<span class="string">&#x27;RouterLink&#x27;</span>, &#123;</span><br><span class="line">      <span class="attr">props</span>: &#123;</span><br><span class="line">        <span class="attr">to</span>: <span class="title class_">String</span></span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="title function_">render</span>(<span class="params">h</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="title function_">h</span>(<span class="string">&#x27;a&#x27;</span>, &#123;</span><br><span class="line">          <span class="attr">attrs</span>: &#123;</span><br><span class="line">            <span class="attr">href</span>: <span class="string">&#x27;#&#x27;</span> + <span class="variable language_">this</span>.<span class="property">to</span></span><br><span class="line">          &#125;</span><br><span class="line">        &#125;, [<span class="variable language_">this</span>.<span class="property">$slots</span>.<span class="property">default</span>])</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> self = <span class="variable language_">this</span></span><br><span class="line">     </span><br><span class="line">    _Vue.<span class="title function_">component</span>(<span class="string">&#x27;RouterView&#x27;</span>, &#123;</span><br><span class="line">      <span class="title function_">render</span>(<span class="params">h</span>) &#123;</span><br><span class="line">        <span class="keyword">const</span> component = self.<span class="title function_">routerMap</span>(self.<span class="property">app</span>.<span class="property">current</span>)</span><br><span class="line">        <span class="keyword">return</span> <span class="title function_">h</span>(component)</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 事件绑定</span></span><br><span class="line">  <span class="title function_">initEvents</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;hashchange&#x27;</span>, <span class="variable language_">this</span>.<span class="property">onHashChange</span>.<span class="title function_">bind</span>(<span class="variable language_">this</span>))</span><br><span class="line">    <span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;load&#x27;</span>, <span class="variable language_">this</span>.<span class="property">onHashChange</span>.<span class="title function_">bind</span>(<span class="variable language_">this</span>))</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">onHashChange</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">app</span>.<span class="property">current</span> = <span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">hash</span>.<span class="title function_">substr</span>(<span class="number">1</span>) || <span class="string">&#x27;/&#x27;</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 初始化init**</span></span><br><span class="line">  <span class="title function_">init</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="title function_">initRouteMap</span>()</span><br><span class="line">    <span class="title function_">initComponents</span>()</span><br><span class="line">    <span class="title function_">initEvents</span>()</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

        </div>

        

        
            <ul class="post-tags-box">
                
                    <li class="tag-item">
                        <a href="/tags/JavaScript/">#JavaScript</a>&nbsp;
                    </li>
                
                    <li class="tag-item">
                        <a href="/tags/%E4%BD%A0%E7%9F%A5%E9%81%93%E7%9A%84%E7%B3%BB%E5%88%97/">#你知道的系列</a>&nbsp;
                    </li>
                
                    <li class="tag-item">
                        <a href="/tags/Vue-Router/">#Vue Router</a>&nbsp;
                    </li>
                
            </ul>
        

        
            <div class="article-nav">
                
                    <div class="article-prev">
                        <a class="prev"
                           rel="prev"
                           href="/2021/06/12/%E4%BD%A0%E7%9F%A5%E9%81%93%E7%9A%84Vue2.x/"
                        >
                            <span class="left arrow-icon flex-center">
                              <i class="fas fa-chevron-left"></i>
                            </span>
                            <span class="title flex-center">
                                <span class="post-nav-title-item">你知道的Vue2.x</span>
                                <span class="post-nav-item">上一篇</span>
                            </span>
                        </a>
                    </div>
                
                
                    <div class="article-next">
                        <a class="next"
                           rel="next"
                           href="/2021/06/05/%E4%BD%A0%E7%9F%A5%E9%81%93%E7%9A%84Vuex/"
                        >
                            <span class="title flex-center">
                                <span class="post-nav-title-item">你知道的Vuex</span>
                                <span class="post-nav-item">下一篇</span>
                            </span>
                            <span class="right arrow-icon flex-center">
                              <i class="fas fa-chevron-right"></i>
                            </span>
                        </a>
                    </div>
                
            </div>
        

        
    </div>
</div>


                
            </div>

        </div>

        <div class="page-main-content-bottom">
            <footer class="footer">
    <div class="info-container">
        <div class="copyright-info info-item">
            &copy;
            
              <span>2020</span>
              -
            
            2023&nbsp;<i class="fas fa-heart icon-animate"></i>&nbsp;<a href="/">cheng5.du</a>
        </div>
        
        <div class="theme-info info-item">
            Powered by <a target="_blank" href="https://hexo.io">Hexo</a>&nbsp;|&nbsp;Theme&nbsp;<a class="theme-version" target="_blank" href="https://github.com/XPoet/hexo-theme-keep">Keep v3.4.5</a>
        </div>
        
        
    </div>
</footer>

        </div>
    </div>

    
        <div class="post-tools">
            <div class="post-tools-container">
    <ul class="tools-list">
        <!-- TOC aside toggle -->
        

        <!-- go comment -->
        
    </ul>
</div>

        </div>
    

    <div class="right-bottom-side-tools">
        <div class="side-tools-container">
    <ul class="side-tools-list">
        <li class="tools-item tool-font-adjust-plus flex-center">
            <i class="fas fa-search-plus"></i>
        </li>

        <li class="tools-item tool-font-adjust-minus flex-center">
            <i class="fas fa-search-minus"></i>
        </li>

        <li class="tools-item tool-expand-width flex-center">
            <i class="fas fa-arrows-alt-h"></i>
        </li>

        <li class="tools-item tool-dark-light-toggle flex-center">
            <i class="fas fa-moon"></i>
        </li>

        <!-- rss -->
        

        
            <li class="tools-item tool-scroll-to-top flex-center">
                <i class="fas fa-arrow-up"></i>
            </li>
        

        <li class="tools-item tool-scroll-to-bottom flex-center">
            <i class="fas fa-arrow-down"></i>
        </li>
    </ul>

    <ul class="exposed-tools-list">
        <li class="tools-item tool-toggle-show flex-center">
            <i class="fas fa-cog fa-spin"></i>
        </li>
        
    </ul>
</div>

    </div>

    

    <div class="image-viewer-container">
    <img src="">
</div>


    

</main>




<script src="/js/utils.js"></script>

<script src="/js/main.js"></script>

<script src="/js/header-shrink.js"></script>

<script src="/js/back2top.js"></script>

<script src="/js/dark-light-toggle.js"></script>








<div class="post-scripts">
    
</div>



</body>
</html>
